<template>
  <h1>商品属性管理</h1>
  <CategorySelect :show="!isShowTable" @getCategoryId="getCategoryId" />

  <el-card style="margin-top: 20px">
    <div v-show="isShowTable">
      <el-button type="primary" icon="plus" :disabled="!category3Id" @click="addAttr">添加属性</el-button>
      <!-- 数据展示 -->
      <el-table :data="attrList" style="width: 100%" border>
        <el-table-column type="index" label="序号" width="80" align="center" />
        <el-table-column prop="attrName" label="属性名称" width="150" />
        <el-table-column prop="prop" label="属性值描述" width="">
          <template v-slot:default="{ row, $index }">
            <el-tag v-for="attrValue in row.attrValueList" :key="attrValue.id" type="success" style="margin: 3px 5px;">
              {{ $index + 1 }}: {{ attrValue.valueName }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template v-slot:default="{ row }">
            <el-button type="warning" icon="edit" @click="updateAttr(row)"></el-button>
            <el-button type="danger" icon="delete"></el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 添加属性|修改属性的结构 -->
    <div v-show="!isShowTable">
      <el-form :model="attrInfo" :inline="true" label-width="100px" ref="form">
        <el-form-item label="属性名称">
          <el-input v-model="attrInfo.attrName" placeholder="请输入属性名称"></el-input>
        </el-form-item>
      </el-form>
      <el-button type="primary" icon="plus" @click="addAttrValue" :disabled="!attrInfo.attrName">添加属性值</el-button>
      <el-button @click="isShowTable = true">取消</el-button>
      <el-table :data="attrInfo.attrValueList" style="width: 100%;margin: 20px 0px;" border>
        <el-table-column type="index" label="序号" width="80" align="center" />
        <el-table-column prop="prop" label="属性值描述" width="width">
          <template v-slot:default="{ row, $index }">
            <el-input v-if="row.flag" :ref="$index" v-model="row.valueName" placeholder="请输入属性值名称" @blur="toLook(row)"
              @keyup.enter="toLook(row)"></el-input>
            <span v-else style="display: block" @click="toEdit(row, $index)">{{ row.valueName }}</span>
          </template>
        </el-table-column>

        <el-table-column width="" prop="prop" label="操作">
          <template v-slot="{ row }"> <!-- 确保这里有 row -->
            <el-popconfirm :title="`确定删除${row.valueName}?`" @confirm="deleteAttrValue(row)">
              <template #reference>
                <el-button icon="delete" type="danger">Delete</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <el-button type="primary" :disabled="attrInfo.attrValueList.length < 1" @click="addOrUpdateAttr">保存</el-button>
      <el-button @click="isShowTable = true">取消</el-button>

    </div>

  </el-card>
</template>

<script>
import { reqAttrList } from '@/api/product/attr';
export default {
  name: "AttrIndex",
  data() {
    return {
      isShowTable: true, // 控制table表格显示与隐藏的状态
      category1Id: "",
      category2Id: "",
      category3Id: "",
      attrList: [],
      // 收集新增属性|修改属性使用的
      attrInfo: {
        attrName: '', // 属性名
        attrValueList: [
          // 属性值，因为属性值可以有多个因此用数组，每一个属性值都是一个对象需要attrId，valueName
        ],
        categoryId: 0, // 三级分类的id
        categoryLevel: 3 // 因为服务器也需要区分几级id
      },
    };
  },
  methods: {
     // 自定义事件的回调
     getCategoryId({ categoryId, level }) {
      // 区分三级分类相应的id，以及父组件进行存储
      if (level === 1) {
        this.category1Id = categoryId
        this.category2Id = ''
        this.category3Id = ''
      } else if (level === 2) {
        this.category2Id = categoryId
        this.category3Id = ''
      } else {
        // 代表三级分类的id有了
        this.category3Id = categoryId
        // 发请求获取平台的属性数据
        this.getAttrList()
      }
    },
     // 获取平台属性的数据
    // 当用户确定三级分类的数据时候，可以向服务器发请求获取平台属性进行展示
    async getAttrList() {
      // 获取分类的ID
      const { category1Id, category2Id, category3Id } = this
      // 获取属性列表的数据
      const result = await reqAttrList(
        category1Id,
        category2Id,
        category3Id
      )
      if (result.code === 200) {
        this.attrList = result.data
      }
    },


    // 添加属性按钮的回调
    addAttr() {
      // 切换table显示与隐藏
      this.isShowTable = false
      // 清除数据
      // 收集三级分类的id
      this.attrInfo = {
        attrName: '', // 属性名
        attrValueList: [
          // 属性值，因为属性值可以有多个因此用数组，每一个属性值都是一个对象需要attrId，valueName
        ],
        categoryId: this.category3Id, // 三级分类的id
        categoryLevel: 3 // 因为服务器也需要区分几级id
      }
    },

    // 添加属性值回调
    addAttrValue() {
      // 向属性值的数组里面添加元素
      // attrId：是你相应的属性的id，目前而言我们是添加属性的操作，还没有相应的属性的id，目前而言带给服务器的id为undefined
      // valueName:相应的属性值的名称
      this.attrInfo.attrValueList.push({
        attrId: this.attrInfo.id, // 对于修改某一个属性的时候，可以在已有的属性值基础之上新增新的属性值（新增属性值的时候，需要把已有的属性的id带上）
        valueName: '',
        flag: true
      })
      // flag属性：给每一个属性值添加一个标记flag，用户切换查看模式与编辑模式，好处，每一个属性值可以控制自己的模式切换
      // 当前flag属性，响应式数据（数据变化视图跟着变化）
      this.$nextTick(() => {
        this.$refs[this.attrInfo.attrValueList.length - 1].focus()
      })
    },

    // 失却焦点的事件---切换为查看模式，展示span
    toLook(row) {
      // 如果属性值为空不能作为新的属性值，需要给用户提示，让他输入一个其他的属性值
      if (row.valueName.trim() === '') {
        this.$message('请你输入一个正常的属性值')
        return
      }
      // 新增的属性值不能与已有的属性值重复
      const isRepat = this.attrInfo.attrValueList.some(item => {
        // 需要将row从数组里面判断的时候去除
        // row最新新增的属性值【数组的最后一项元素】
        // 判断的时候，需要把已有的数组当中新增的这个属性值去除
        if (row !== item) {
          return row.valueName === item.valueName
        }
      })

      if (isRepat) return
      // row：形参是当前用户添加的最新的属性值
      // 当前编辑模式变为查看模式【让input消失，显示span】
      row.flag = false
    },
    // 点击span的回调，变为编辑模式
    toEdit(row, index) {
      row.flag = true
      // 获取input节点，实现自动聚焦
      // 需要注意：点击span的时候，切换为input变为编辑模式，但是需要注意，对于浏览器而言，页面重绘与重拍耗时间的
      // 点击span的时候，重绘重拍一个input它是需要耗费事件，因此我们不可能一点击span立马获取到input
      // $nextTick,当节点渲染完毕了，会执行一次
      this.$nextTick(() => {
        // 获取相应的input表单元素实现聚焦
        this.$refs[index].focus()
      })
    },
    // 气泡确认框确定按钮的回调
    // 最新版本的ElementUI----2.15.6，目前模板中的版本号2.13.x
    deleteAttrValue(index) {
      // 当前删除属性值的操作是不需要发请求的
      // 删除数组的第index个元素
      this.attrInfo.attrValueList.splice(index, 1)
    },


    // 保存按钮：进行添加属性或者修改属性的操作
    async addOrUpdateAttr() {
      // 整理参数:1,如果用户添加很多属性值，且属性值为空的不应该提交给服务器
      // 提交给服务器数据当中不应该出现flag字段
      this.attrInfo.attrValueList = this.attrInfo.attrValueList.filter(item => {
        // 过滤掉属性值不是空的
        if (item.valueName !== '') {
          // 删除掉flag属性
          delete item.flag
          return true
        }
      })
      try {
        // 发请求
        await this.$API.attr.reqAddOrUpdateAttr(this.attrInfo)
        // 展示平台属性的信号量进行切换
        this.isShowTable = true
        // 提示消失
        this.$message({ type: 'success', message: '保存成功' })
        // 保存成功以后需要再次获取平台属性进行展示
        this.getAttrList()
      } catch (error) {
        // this.$message('保存失败')
      }
    },

    // 修改某一个属性
    updateAttr(row) {
      // isShowTable变为false
      this.isShowTable = false;
      // 直接引用传入的 row，这样 row 的变化会原地反映在 attrInfo 上
      this.attrInfo = row;
      // 为每个属性值元素添加 flag 标记
      this.attrInfo.attrValueList.forEach((item) => {
         // 确保 flag 存在且默认为 false
        item.flag = item.flag || false;
      });
    }

  }
}
</script>


<style scoped>
h1 {
  margin:10px 0px;
  font-size: 24px;
  color: #00197c;
  font-weight: bold;
}

</style>